// @Author：bishisimo 2021/4/30 上午10:18
// @Description：
package main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"errors"
	"fmt"
	"github.com/lucas-clemente/quic-go"
	"github.com/lucas-clemente/quic-go/http3"
	"net/http"
	. "quic-demo/logger"
	"quic-demo/utils"
)

func main() {
	err := Client("localhost:4433")
	if err != nil {
		Logger.Err(err).Send()
		return
	}
}
func Client4http3(addr string) error {
	pool, err := x509.SystemCertPool()
	Logger.Fatal().Err(err)
	if err != nil {
		return err
	}
	roundTripper := &http3.RoundTripper{
		TLSClientConfig: &tls.Config{
			RootCAs:            pool,
			InsecureSkipVerify: false,
		},
	}
	defer roundTripper.Close()
	hclient := &http.Client{
		Transport: roundTripper,
	}
	rsp, err := hclient.Get(addr)
	if rsp==nil{
		return errors.New("body is nil")
	}
	utils.Println(rsp.Body)
	return nil
}

func Client(addr string) error {
	tlsConf := &tls.Config{
		InsecureSkipVerify: true,
		NextProtos:         []string{"all"},

	}
	session, err := quic.DialAddr(addr, tlsConf, nil)
	Logger.Fatal().Err(err)
	if err != nil {
		return err
	}
	stream, err := session.OpenStreamSync(context.Background())
	Logger.Error().Err(err)

	txChan:=make(chan string,10)
	rxChan:=make(chan string,10)
	errChan:=make(chan error)
	go Receive(stream,rxChan,errChan)
	go Input(txChan,errChan)
	for  {
		select {
		case msg:=<-txChan:
			_, err := stream.Write([]byte(msg))
			if err != nil {
				Logger.Err(err)
				return err
			}
		case msg:=<-rxChan:
			Logger.Info().Str("Msg",msg).Send()
		case err:=<-errChan:
			return err
		}
	}
}

func Input(txChan chan string,errChan chan error)  {
	for {
		fmt.Println("input>")
		message:=""
		_, err := fmt.Scanln(&message)
		if err != nil {
			Logger.Error().Err(err).Msg("input message err")
			errChan<-err
			return
		}
		txChan<-message
	}
}

func Receive(stream quic.Stream,rxChan chan string,errChan chan error)  {
	for  {
		buf := make([]byte, 10)
		n, err := stream.Read(buf)
		if err != nil {
			Logger.Error().Err(err).Msg("input message err")
			errChan<-err
			return
		}
		rxChan<-string(buf[:n])
	}
}
